package main

import (
	"fmt"
	"time"
)

/**

常见的关闭协程的原因有如下几种：

1.goroutine 自己跑完结束退出
2.主进程crash退出，goroutine 被迫退出
3.通过通道发送信号，引导协程的关闭。

第一种，属于正常关闭，不在今天讨论范围之内。
第二种，属于异常关闭，应当优化代码。
第三种，才是开发者可以手动控制协程的方法，即本代码的示例

**/

func main() {
	stop := make(chan bool)

	go func() {
		for { //这里的无限循环，是在模拟一个一直在运行而不会退出的协程
			select { //这里不能用if代替select。 select，有”非阻塞“的功能，就是遇到阻塞的代码，就会执行default块
			case <-stop: //这个stop信道，可以理解为外部传来的一个信号，用于告知是否需要结束协程。如果这里改用if，就会阻塞
				fmt.Println("监控退出，停止了...")
				return
			default: //这段代码可以理解为，只要没有接收终止的信息，就会一直执行
				fmt.Println("goroutine监控中...")
				time.Sleep(2 * time.Second)
			}
		}
	}()

	time.Sleep(10 * time.Second)
	fmt.Println("可以了，通知监控停止")
	stop <- true //发送终止信号
	//为了检测监控过是否停止，如果没有监控输出，就表示停止了
	time.Sleep(5 * time.Second)

}
